package com.johnson.news.util;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;

import com.johnson.news.BuildConfig;
import com.johnson.news.R;
import com.johnson.news.model.bean.DataNewsStatus;
import com.johnson.news.model.bean.NewsItem;
import com.johnson.news.model.bean.UpdateItem;
import com.johnson.news.model.bean.UserContent;
import com.johnson.news.model.remote.RemoteDataSource;
import com.johnson.news.model.util.NewsPreference;
import com.youmbe.library.util.MyToast;
import com.youmbe.library.util.SerializeUtil;
import com.youmbe.library.view.MyProgressDialog;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.sql.Date;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import androidx.core.content.FileProvider;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class Utils {
	
	public static final String MID = "31";
	public static final int PAGE_SIZE = 20;
	public static final int DEFAULT_PIC_WIDTH = 480;
	public static final int DEFAULT_PIC_HEIGHT = 250; 
	public static final int DEFAULT_CONTENT_PIC_HEIGHT = 320; 
	public static final String LAUNCH_PIC_NAME = "launch_pic.png";
	public static final String SHARE_PIC_NAME = "share.png";
	public static final String SYSTEM = "3";
	
	public static final String QQ_APPID = "1104905484";
	public static final String QQ_APPKEY = "uh4eoTbr10UPtJ17";
	public static final String WEIXIN_APPID = "wxa59be964e3999519";
	public static final String WEIXIN_SECRET = "50981e4771d2b71b3b34b9acc6e7892d";
	public static final String UMENG_APPKEY = "561c5f9767e58e48550052d4";
	public static final String BAIDU_PUSH_APPKEY = "uBVKjoFrwxU4blL9xckTOpUf";
	public static final String BAIDU_PUSH_KEYSECRET = "G8tzNZUViih7niX9WEGyu4DreBgIGhjQ";
	public final static String NEWS_UMENG = "news_umeng";
	public final static String APP_SOURCE = "1";
	public final static String SYSTEM_FIELD_ANDROID = "3";
	public final static int DEFAULT_LOAD_TIME = 1000;
	public final static int DELAY_LOAD_TIME = 2500;
	
	public static final String LINK_CHANNEL = "0";
	public static final String SINA_CHANNEL = "1";
	public static final String TENCENT_CHANNEL = "2";
	public static final String SMS_CHANNEL = "3";
	public static final String EMAIL_CHANNEL = "4";
	public static final String RENREN_CHANNEL = "5";
	public static final String DOUBAN_CHANNEL = "6";
	public static final String WEIXIN_CHANNEL = "7";
	public static final String WEIXIN_CIRCLE_CHANNEL = "8";
	public static final String QZONE_CHANNEL = "9";
	public static final String QQFRIEND_CHANNEL = "10";
	
	public static enum REQUEST_CATEGORY{
		GET_TOP_NEWS,GET_NEWS,GET_NEW_CONTENT,GET_CONTINUE_NEWS,
		GET_SEARCH_NEWS
	}

	public static int screenHeight, screenWidth, statusBarHeight, bottomNavigationBarHeight;

	public static HashMap<String, DataNewsStatus> newsStatusMap = new HashMap<>();//无相应接口，暂存本地

//	public static UserContent userContent;

//	public static String userToken;

	public static String channelId;

	/**
	 * 获取屏幕长宽
	 *
	 * @param context
	 */
	public static void getScreenWH(Context context) {
		WindowManager w = ((Activity) context).getWindowManager();
		Display d = w.getDefaultDisplay();
		DisplayMetrics metrics = new DisplayMetrics();
		d.getMetrics(metrics);
		screenWidth = metrics.widthPixels;
		screenHeight = metrics.heightPixels;
		if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17) try {
			screenHeight = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
		} catch (Exception e) {
			e.printStackTrace();
		}
		else if (Build.VERSION.SDK_INT >= 17) {
			try {
				android.graphics.Point realSize = new android.graphics.Point();
				Display.class.getMethod("getRealSize", android.graphics.Point.class).invoke(d, realSize);
				screenHeight = realSize.y;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void initSerializeData(Context context) {
//		userContent = (UserContent) SerializeUtil.readSerializeData(context, Constants.serialize_user);
		newsStatusMap = (HashMap)SerializeUtil.readSerializeData(context, Constants.serialize_news_status_new);
		if(newsStatusMap == null)
			newsStatusMap = new HashMap<>();
//		Object token = SerializeUtil.readSerializeData(context, Constants.serialize_user_token);
//		if(token != null)
//			userToken = token.toString();
	}

	public static void saveUserContent(Context context) {
//		SerializeUtil.serializeData(context, userContent, Constants.serialize_user);
	}

//	public static void saveUserToken(Context context, String token) {
//		userToken = token;
//		SerializeUtil.serializeData(context, token, Constants.serialize_user_token);
//	}

	public static void updateNewsStatus(Context context, NewsItem item, boolean like, boolean collect) {
//		String phone = NewsPreference.getinstance(context).getLoginName();
		if(newsStatusMap == null)//TextUtils.isEmpty(phone) ||
			return;

		String key = item.getItemid();//getKeyOfNewsStatus(NewsPreference.getinstance(context).getLoginName(), item.getItemid());
		DataNewsStatus dataNewsStatus;
		if(!newsStatusMap.containsKey(key)) {
			dataNewsStatus = new DataNewsStatus();
		} else
			dataNewsStatus = newsStatusMap.get(key);

		newsStatusMap.put(key, dataNewsStatus);

		dataNewsStatus.newsItem = item;
		dataNewsStatus.liked = like;
		dataNewsStatus.collected = collect;

		saveNewsStatus(context);
	}

	public static void saveNewsStatus(Context context) {
		SerializeUtil.serializeData(context, newsStatusMap, Constants.serialize_news_status_new);
	}

	public static void LOG(String TAG, String txt) {
		Log.d(TAG, txt);
	}
	
	public static boolean isEmptyString(String s){
		if(s == null || s.equals("")){
			return true;
		}
		return false;
	}
	
	/**
	 * @param context
	 * @return
	 */
	public static String getVersionName(Context context) {
		String strVersionName = null;

		try {
			String packageName = context.getPackageName();
			PackageInfo info = context.getPackageManager().getPackageInfo(
					packageName, 0);
			if (null != info) {
				strVersionName = info.versionName;
			}
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}

		return strVersionName;
	}
	

	/**
	 * @param context
	 * @return
	 */
	public static boolean isNetworkAvailable(Context context) {

		try {
			ConnectivityManager cm = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo info = cm.getActiveNetworkInfo();
			if (null != info && info.isConnected()) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * @param context
	 * @return
	 */
	public static int getVersionCode(Context context) {
		int versionCode = 0;

		try {
			String packageName = context.getPackageName();
			PackageInfo info = context.getPackageManager().getPackageInfo(
					packageName, 0);
			if (null != info) {
				versionCode = info.versionCode;
			}
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}

		return versionCode;
	}
	
	public static boolean testPwd(String password) {
//		if (password.matches("^([a-z]*|[0-9]*|[a-z0-9]{0,7}|[^a-z0-9]*)$")) {
//			return false;
//		}
		if(password.length() < 6 || password.length() > 12){
			return false;
		}
		return true;
	}
	
	public static ArrayList<String> SplitString(String s, String format) {
		String[] ss;
		ArrayList<String> innerUrl = new ArrayList<String>();
		ss = s.split(format);
		for (int i = 0; i < ss.length; i++) {
			innerUrl.add(ss[i]);
		}
		return innerUrl;
	}
	
	public static boolean isPhone(String phoneStr){
		if (phoneStr == null)
			return false;
		String phoneRegex = "^((\\+86)?(86)?)\\s*1\\d{10}";
		return phoneStr.matches(phoneRegex);
	}
	
	public static boolean isEmail(String strEmail) {
		String strPattern = "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" + "\\@"
				+ "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" + "(" + "\\."
				+ "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" + ")+";
		Pattern p = Pattern.compile(strPattern);
		Matcher m = p.matcher(strEmail);
		return m.matches();
	}

	
	public static String formatTime(long time){
		
		SimpleDateFormat sdformat = new SimpleDateFormat("MM-dd HH:mm:ss");//24小时制
		Date date = new Date(time*1000);
        String LgTime = sdformat.format(date);
        return LgTime;
	}
	
	public static String getRecordTime(long timestamp) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		Date date = new Date(timestamp);
		return sdf.format(date);
	}
	
	public static String formatTime(long time, String format){
		SimpleDateFormat sdformat = new SimpleDateFormat(format);//24小时制
		Date date = new Date(time);
        String LgTime = sdformat.format(date);
        return LgTime;
	}
	/**
	 * 将unicode 编码转为utf-8
	 * @param theString
	 * @return
	 */
	public static String decodeUnicode(String theString) {
		char aChar;
		int len = theString.length();
		StringBuffer outBuffer = new StringBuffer(len);
		for (int x = 0; x < len;) {
			aChar = theString.charAt(x++);
			if (aChar == '\\') {
				aChar = theString.charAt(x++);
				if (aChar == 'u') {
					// Read the xxxx
					int value = 0;
					for (int i = 0; i < 4; i++) {
						aChar = theString.charAt(x++);
						switch (aChar) {
						case '0':
						case '1':
						case '2':
						case '3':
						case '4':
						case '5':
						case '6':
						case '7':
						case '8':
						case '9':
							value = (value << 4) + aChar - '0';
							break;
						case 'a':
						case 'b':
						case 'c':
						case 'd':
						case 'e':
						case 'f':
							value = (value << 4) + 10 + aChar - 'a';
							break;
						case 'A':
						case 'B':
						case 'C':
						case 'D':
						case 'E':
						case 'F':
							value = (value << 4) + 10 + aChar - 'A';
							break;
						default:
							throw new IllegalArgumentException(
									"Malformed   \\uxxxx   encoding.");
						}

					}
					outBuffer.append((char) value);
				} else {
					if (aChar == 't')
						aChar = '\t';
					else if (aChar == 'r')
						aChar = '\r';
					else if (aChar == 'n')
						aChar = '\n';
					else if (aChar == 'f')
						aChar = '\f';
					outBuffer.append(aChar);
				}
			} else
				outBuffer.append(aChar);
		}
		return outBuffer.toString();
	}
	
	public static String getPhoneDeviceId(Context context){
		TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
		return tm.getDeviceId();
	}
	
	// IMSI
	public static String getSubscriberId(Context context){
		TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
		return tm.getSubscriberId();
	}
	
	public static void hideIME(Context context, View view) {
		if (view != null) {
			InputMethodManager imm = (InputMethodManager) context
					.getSystemService(Context.INPUT_METHOD_SERVICE);
			// imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
			imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
		}
	}
	
//	public static void openNewsContent(Context context, String itemid,
//                                       String catid, String title, boolean fromPush, boolean isHotNews,
//                                       String mid){
//		Intent intent = new Intent(context,NewsContentActivity.class);
//		intent.putExtra("title", title);
//		intent.putExtra("catid", catid);
//		intent.putExtra("itemid", itemid);
//		intent.putExtra("fromPush", fromPush);
//		intent.putExtra("isHotNews", isHotNews);
//		intent.putExtra("mid", mid);
//		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//		context.startActivity(intent);
//	}
//
//	public static void openAskmeReply(Context context, String itemid,
//                                      String title, boolean fromMessage, boolean isHotNews){
//		Intent intent = new Intent(context,AskmeReplyActivity.class);
//		intent.putExtra("title", title);
//		intent.putExtra("itemid", itemid);
//		intent.putExtra("fromPush", fromMessage);
//		intent.putExtra("isHotNews", isHotNews);
//		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//		context.startActivity(intent);
//	}
	
	/**
	 * 图片保存到本地
	 * 
	 * @param in
	 * @param fileName
	 * @throws IOException
	 */
	public static void saveBitmap2File(InputStream in, String dirPath, String fileName)
			throws IOException {

		if (in == null) {
			return;
		}

		if (dirPath == null || dirPath.equals("")) {
			return;
		}

		if (fileName == null || fileName.equals("")) {
			return;
		}

		if (!Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			return;
		}

		File dir = new File(dirPath);
		if (!dir.exists()) {
			dir.mkdirs();
		}

		File file = new File(dirPath + fileName);
		if (!file.exists()) {
			file.createNewFile();
		}

		OutputStream out = new FileOutputStream(file);
		byte[] buffer = new byte[1024];
		int length = -1;

		while ((length = in.read(buffer)) != -1) {
			out.write(buffer, 0, length);
		}

		out.flush();
		out.close();
	}
	
	public static byte[] Bitmap2Bytes(Bitmap bitmap) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
		return baos.toByteArray();
	}
	
	public static byte[] Bitmap2Bytes(Context context, int resId) {
		Bitmap bmp = BitmapFactory
				.decodeResource(context.getResources(), resId);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bmp.compress(Bitmap.CompressFormat.PNG, 100, baos);
		return baos.toByteArray();
	}
	
	public static byte[] inputStreamToByte(InputStream is) {
		ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
		int ch;
		try {
			while ((ch = is.read()) != -1) {
				bytestream.write(ch);
			}
			byte imgdata[] = bytestream.toByteArray();
			bytestream.close();
			return imgdata;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static Bitmap getBitmap(Context context, String fileName) {

		Bitmap image = null;
		try {
			FileInputStream s = new FileInputStream(new File(fileName));
			image = BitmapFactory.decodeStream(s);
			s.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return image;
	}
	
	public static Bitmap getBitmapByFilePath(Context context, String path) {

		Bitmap image = null;
		try {
			FileInputStream s = new FileInputStream(path);
			image = BitmapFactory.decodeStream(s);
			s.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return image;
	}
	
	public static boolean isSDCardExisted() {
		boolean isSDCardExisted = false;
		String status = Environment.getExternalStorageState();
		if (status.equals(Environment.MEDIA_MOUNTED)) {
			isSDCardExisted = true;
		}
		return isSDCardExisted;
	}

	public static int parseInt(Object object) {
		try {
			return Integer.parseInt(object.toString());
		} catch (Exception e) {
			return 0;
		}
	}

	public static long parseLong(Object object) {
		try {
			return Long.parseLong(object.toString());
		} catch (Exception e) {
			return 0;
		}
	}

	public static float parseFloat(Object object) {
		try {
			return Float.parseFloat(object.toString());
		} catch (Exception e) {
			return 0;
		}
	}

	public static boolean parseBoolean(Object object) {
		try {
			return Boolean.parseBoolean(object.toString());
		} catch (Exception e) {
			return false;
		}
	}

	public static String formatFloat(float num) {
		DecimalFormat decimalFormat=new DecimalFormat("0.00");//构造方法的字符格式这里如果小数不足2位,会以0补足.
		String p = decimalFormat.format(num);
		return p;
	}

	/**
	 * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
	 */
	public static int pxTodip(Context context, float pxValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (pxValue / scale + 0.5f);
	}

	/**
	 * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
	 */
	public static int dipTopx(Context context, float dpValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (dpValue * scale + 0.5f);
	}

	/**
	 * 获取通知栏的高度
	 *
	 * @param context
	 * @return
	 */
	public static int getStatusBarHeight(Context context) {
		Class<?> c = null;
		Object obj = null;
		Field field = null;
		int x = 0, statusBarHeight = 0;
		try {
			c = Class.forName("com.android.internal.R$dimen");
			obj = c.newInstance();
			field = c.getField("status_bar_height");
			x = Integer.parseInt(field.get(obj).toString());
			statusBarHeight = context.getResources().getDimensionPixelSize(x);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return statusBarHeight;
	}

	//底部导航栏高度
	public static int getNavigationBarHeight(Context context) {
		Resources resources = context.getResources();
		int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
		bottomNavigationBarHeight = resources.getDimensionPixelSize(resourceId);
		Log.e("日志", "底部Navigationbar高度:" + bottomNavigationBarHeight);
		return bottomNavigationBarHeight;
	}

	/**
	 * 获取应用根目录
	 *
	 * @param c
	 * @return
	 */
	public static String getPath(Context c) {
		String path = null;
		if (c == null) return null;
		File file = null;
		if (isSdcardInsert()) {
			File sdDir = Environment.getExternalStorageDirectory();
			path = sdDir.toString() + File.separator + Constants.rootPath;
		} else {
			path = c.getFilesDir().getPath() + File.separator + Constants.rootPath;
		}
		file = new File(path);
		if (!file.exists()) file.mkdirs();
		return path;
	}

	/**
	 * 判断是否有SD卡
	 *
	 * @return
	 */
	public static boolean isSdcardInsert() {
		boolean isInsert = false;
		String state = Environment.getExternalStorageState();
		if (!state.equals(Environment.MEDIA_MOUNTED)) {
			isInsert = false;
		} else isInsert = true;
		return isInsert;
	}

	public static boolean hasLikedNews(Context context, String newsId) {
//		if(!NewsPreference.getinstance(context).getLoginState())
//			return false;
		String key = newsId;//getKeyOfNewsStatus(NewsPreference.getinstance(context).getLoginName(), newsId);
		if(TextUtils.isEmpty(key) || newsStatusMap.size() == 0 || !newsStatusMap.containsKey(key)) {
			return false;
		} else
			return newsStatusMap.get(key).liked;
	}

	public static boolean hasCollectedNews(Context context, String newsId) {
//		if(!NewsPreference.getinstance(context).getLoginState())
//			return false;
		String key = newsId;//getKeyOfNewsStatus(NewsPreference.getinstance(context).getLoginName(), newsId);
		if(TextUtils.isEmpty(key) || newsStatusMap.size() == 0 || !newsStatusMap.containsKey(key)) {
			return false;
		} else
			return newsStatusMap.get(key).collected;
	}

	private static String getKeyOfNewsStatus(String phone, String newsId) {
		return phone + "___" + newsId;
	}

	public static boolean isWeixinAvilible(Context context) {
		final PackageManager packageManager = context.getPackageManager();// 获取packagemanager
		List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);// 获取所有已安装程序的包信息
		if (pinfo != null) {
			for (int i = 0; i < pinfo.size(); i++) {
				String pn = pinfo.get(i).packageName;
				if (pn.equals("com.tencent.mm")) {
					return true;
				}
			}
		}

		return false;
	}

	/**
	 * 判断qq是否可用
	 *
	 * @param context
	 * @return
	 */
	public static boolean isQQClientAvailable(Context context) {
		final PackageManager packageManager = context.getPackageManager();
		List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
		if (pinfo != null) {
			for (int i = 0; i < pinfo.size(); i++) {
				String pn = pinfo.get(i).packageName;
				if (pn.equals("com.tencent.mobileqq")) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 判断qq是否可用
	 *
	 * @param context
	 * @return
	 */
	public static boolean isWeiboClientAvailable(Context context) {
		final PackageManager packageManager = context.getPackageManager();
		List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
		if (pinfo != null) {
			for (int i = 0; i < pinfo.size(); i++) {
				String pn = pinfo.get(i).packageName;
				if (pn.equals("com.sina.weibo")) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 清空文件夹
	 *
	 * @param file
	 */
	public static void deleteDir(File file) {
		if (file.exists()) {
			if (file.isFile()) {
				file.delete();
			} else if (file.isDirectory()) {
				File files[] = file.listFiles();
				for (int i = 0; i < files.length; i++) {
					deleteDir(files[i]);
				}
			}
			file.delete();
		} else {

		}
	}

	/**
	 * 获取文件夹大小
	 *
	 * @param f
	 * @return
	 */
	public static long getFileSize(File f) {
		if (!f.exists()) {
			return 0;
		}
		long size = 0;
		File flist[] = f.listFiles();
		if (flist != null && flist.length > 0) {
			for (int i = 0; i < flist.length; i++) {
				if (flist[i].isDirectory()) {
					size = size + getFileSize(flist[i]);
				} else {
					size = size + flist[i].length();
				}
			}
		}
		return size;
	}

	/**
	 * 转换文件大小
	 *
	 * @param fileS
	 * @return
	 */
	public static String formetFileSize(long fileS) {
		DecimalFormat df = new DecimalFormat("#.00");
		String fileSizeString = "";
		String wrongSize = "0B";
		if (fileS == 0) {
			return wrongSize;
		}
		if (fileS < 1024) {
			fileSizeString = df.format((double) fileS) + "B";
		} else if (fileS < 1048576) {
			fileSizeString = df.format((double) fileS / 1024) + "KB";
		} else if (fileS < 1073741824) {
			fileSizeString = df.format((double) fileS / 1048576) + "MB";
		} else {
			fileSizeString = df.format((double) fileS / 1073741824) + "GB";
		}
		return fileSizeString;
	}

	/**
	 * 获取当前SDK版本号
	 *
	 * @return
	 */
	public static int getAndroidSDKVersion() {
		int version = 0;
		try {
			version = Build.VERSION.SDK_INT;
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return version;
	}

	public static void checkUpdate(final Context context, final boolean isAutoCheck) {
		RemoteDataSource.getRemoteDataSource()
				.checkUpdate(getVersionCode(context), Constants.app_type)
				.subscribe(new Consumer<UpdateItem>() {
					@Override
					public void accept(final UpdateItem updateItem) throws Exception {
						int status = parseInt(updateItem.getStatus());
						if(status == 0) {//已经是最新版本无需升级
							if(!isAutoCheck) {
								AlertDialog.Builder builder = new AlertDialog.Builder(context, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
								builder.setMessage("您的当前版本是最新版本。");
								builder.setTitle("提示");
								builder.setPositiveButton(context.getString(R.string.ok), new AlertDialog.OnClickListener() {
									@Override
									public void onClick(DialogInterface dialog, int which) {
										// TODO Auto-generated method stub
									}
								});
								builder.create().show();
							}
						} else if(status == 1) {//发现新版本
							AlertDialog.Builder builder = new AlertDialog.Builder(context, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
							builder.setMessage("发现新版本。\r\n 是否立即更新？");
							builder.setTitle("提示");
							builder.setPositiveButton(context.getString(R.string.ok), new AlertDialog.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog, int which) {
									String downloadUrl = updateItem.getDownurl();
									if (getAndroidSDKVersion() < 11) {
										if (!TextUtils.isEmpty(downloadUrl)) {
											Uri uri = Uri.parse(downloadUrl);
											Intent intent = new Intent(Intent.ACTION_VIEW, uri);
											context.startActivity(intent);
										}
									} else {
										if(!TextUtils.isEmpty(downloadUrl)) {
											String savedPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
													+ File.separator + context.getString(R.string.app_name)
													+ File.separator + downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1);
											startDownload(context, downloadUrl, savedPath);

										} else {
											MyToast.showToast("下载失败，请稍后重试", context);
										}
									}
								}
							});
							builder.setNegativeButton(context.getString(R.string.cancel), new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialogInterface, int i) {

								}
							});
							builder.create().show();
						} else if(status == 2) {//未获取到版本号

						}
					}
				});
	}

	private static MyProgressDialog progressDialog;
	public static void startDownload(final Context context, String url, final String savedPath) {
		downloadFile(url, savedPath)
				.subscribeOn(Schedulers.io())
				.observeOn(AndroidSchedulers.mainThread())
				.doOnSubscribe(new Consumer<Disposable>() {
					@Override
					public void accept(Disposable disposable) throws Exception {
						progressDialog = MyProgressDialog.show(context, "下载中...", false, false);
					}
				}).doFinally(new Action() {
			@Override
			public void run() throws Exception {
				progressDialog.dismiss();
				progressDialog = null;
			}
		}).subscribe(new Consumer<String>() {
			@Override
			public void accept(String s) throws Exception {

			}
		}, new Consumer<Throwable>() {
			@Override
			public void accept(Throwable throwable) throws Exception {
				throwable.printStackTrace();
				MyToast.showToast("下载失败，请稍后重试。", context);
			}
		}, new Action() {
			@Override
			public void run() throws Exception {
				installAPK(context, new File(savedPath));
			}
		});

	}

	public static Observable<String> downloadFile(final String targetUrl, final String savePath) {
		return Observable.create(new ObservableOnSubscribe<String>() {
			@Override
			public void subscribe(ObservableEmitter<String> emitter) throws Exception {

				String parentPath = savePath.substring(0, savePath.lastIndexOf("/"));
				File parentFile = new File(parentPath);
				boolean createRet = false;
				if(!parentFile.exists())
					createRet = parentFile.mkdirs();

				InputStream inputStream = null;
				OutputStream outputStream = null;
				OkHttpClient client = new OkHttpClient();
				Request request = new Request.Builder()
						.url(targetUrl)
						.build();
				try{
					Response response = client.newCall(request).execute();
					if (response.isSuccessful()){
						inputStream = response.body().byteStream();
						long length = response.body().contentLength();
						//将文件下载到file路径下
						outputStream = new FileOutputStream(savePath);
						byte data[] = new byte[1024];
						emitter.onNext("0%");
						long total = 0;
						int count;
						while ((count = inputStream.read(data)) != -1){
							total += count;
							// 返回当前实时进度
							emitter.onNext(String.valueOf(total*100/length) + "%");
							outputStream.write(data,0,count);
						}
						outputStream.flush();
						outputStream.close();
						inputStream.close();
					}
				}catch (IOException e){
					//告诉订阅者错误信息
					emitter.onError(e);
				}finally {
					if (inputStream != null){
						try{
							inputStream.close();
						}catch (IOException e){}
					}
					if (outputStream != null){
						try {
							outputStream.close();
						}catch (IOException e){}
					}
				}
				//告诉订阅者请求数据结束
				emitter.onComplete();

			}
		});
	}


	//下载到本地后执行安装
	public static void installAPK(Context mContext, File file) {
		if (!file.exists())
			return;

		Intent intent = new Intent(Intent.ACTION_VIEW);

		if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) {

			Uri contentUri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".FileProvider",file);

			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

			intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

			intent.setDataAndType(contentUri,"application/vnd.android.package-archive");
			mContext.startActivity(intent);

		} else {
			Uri uri = Uri.parse("file://" + file.toString());
			intent.setDataAndType(uri, "application/vnd.android.package-archive");
			//在服务中开启activity必须设置flag,后面解释
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			mContext.startActivity(intent);
		}
	}


	/**
	 * 验证手机号的合法性
	 *
	 * @param phone
	 * @return
	 */
	public static boolean verifyPhone(String phone) {
		String rule = "^1(3|5|7|8|4)\\d{9}";
		Pattern p = Pattern.compile(rule);
		Matcher m = p.matcher(phone);
		if (!m.matches()) {
			return false;
		} else {
			return true;
		}
	}

	public static String getToken() {//"1585212860"

		return AesEncryptionUtil.encrypt(System.currentTimeMillis() / 1000 + "", Constants.appTokenKey, Constants.iv);

	}


	public static String parseByte2HexStr(byte buf[]) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < buf.length; i++) {
			String hex = Integer.toHexString(buf[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}


}
